package com.jly.Controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jly.Util.ResponseData;
import com.jly.Util.util;
import com.jly.service.RedisService;
import com.jly.Util.Constants;
import com.jly.Util.HttpPOSTUtil;
import com.jly.model.MessageText;
import com.jly.service.RedisService4;
import com.thoughtworks.xstream.XStream;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.*;

@RestController
@RequestMapping("/test")
public class Controller {

    private Logger logger = Logger.getLogger(Controller.class);

    @Autowired
    private RedisService redisService;

    @Autowired
    private RedisService4 redisService4;

    //微信扫描认证的接口
    @RequestMapping(value = "/test",method = RequestMethod.GET)
    public String test(@RequestParam("signature") String signature,
                       @RequestParam("timestamp") String timestamp,
                       @RequestParam("nonce") String nonce,
                       @RequestParam("echostr") String echostr,
                       HttpServletRequest request) {

        logger.info(request.getMethod());
        //排序
        String sortString = sort(Constants.TOKEN, timestamp, nonce);
        //加密
        String myString = sha1(sortString);
        //校验
        if (myString != null && myString != "" && myString.equals(signature)) {
            System.out.println("签名校验通过");
            //如果检验成功原样返回echostr，微信服务器接收到此输出，才会确认检验完成。
            return echostr;
        } else {
            System.out.println("签名校验失败");
            return "";
        }
    }

    //用户操作。微信调用此接口并传输数据
    @RequestMapping(value = "/test",method = RequestMethod.POST)
    public void test(HttpServletRequest request, HttpServletResponse response) {
        try {
            response.setCharacterEncoding("utf-8");
            Map<String, String> map = xmlToMap(request);
            String ToUserName = map.get("ToUserName");
            String FromUserName = map.get("FromUserName");
            String MsgType = map.get("MsgType");
            String Content = map.get("Content");
            String Event = map.get("Event");
            String message = null;
            PrintWriter out = null;
            System.out.println(ToUserName);
            System.out.println(FromUserName);
            if("text".equals(MsgType)){
                    message = initMessage(FromUserName,ToUserName,Content);
            }else if("subscribe".equals(Event)){
                message = initMessage(FromUserName, ToUserName, "欢迎关注");
            }
            //模板消息推送成功后告知返回结果存入redis
            if("TEMPLATESENDJOBFINISH".equals(Event)){
                JSONObject json = JSON.parseObject(JSON.toJSONString(map));
                if(!json.getString("Status").equals("success")){
                    json.put("data",redisService4.getStringValue(json.getString("MsgID")));
                    redisService4.setListOnLeft(json.getString("MsgID"),json.toJSONString());
                }
            }
            try{
                if(null!=message){
                    out = response.getWriter();
                    out.write(message);
                }
            }catch (Exception e){
                e.printStackTrace();
            }
            if(null!=out){
                out.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //xml转map的方法
    public Map<String,String> xmlToMap(HttpServletRequest request){
        Map<String,String> map = new HashMap<String,String>();
        SAXReader reader = new SAXReader();
        InputStream in = null;
        try {
            in = request.getInputStream();
            Document doc = reader.read(in);
            Element root = doc.getRootElement();
            List<Element> list = root.elements();
            for (Element element : list) {
                map.put(element.getName(), element.getText());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return map;
    }

    //bean 转xml
    public String messageToXml(MessageText message){
        XStream xStream = new XStream();
        xStream.alias("xml",message.getClass());
        return xStream.toXML(message);
    }

    public String initMessage(String FromUserName,String ToUserName,String content){
        MessageText text = new MessageText();
        text.setToUserName(FromUserName);
        text.setFromUserName(ToUserName);
        text.setContent(content);
        text.setCreateTime(new Date().getTime());
        text.setMsgType("text");
        return  messageToXml(text);
    }

    @RequestMapping("/getToken")
    public Object getToken(){
        ResponseData result = new ResponseData();
        try{
            String access_token = util.getToken(redisService);
            result.setCode(Constants.SUCCESS_200);
            result.addData(access_token);
        }catch (Exception e){
            e.printStackTrace();
            result.setCode(Constants.Fail_400);
            result.setMsg(e.getMessage());
        }
        return result;
    }

    @RequestMapping("/createButton")
    public Object createButton(String id){
        JSONObject result = new JSONObject();
        try{
            JSONObject json = JSON.parseObject(id);
            JSONArray array = json.getJSONArray("array");
            JSONObject param = new JSONObject();
            param.put("button",array);
            String results = HttpPOSTUtil.sendPost(Constants.createButtonUrl+"?access_token="+util.getToken(redisService),param.toString());
            result.put("code", 200);
            result.put("data", JSON.parse(results));
        }catch (Exception e){
            e.printStackTrace();
            result.put("code",400);
            result.put("msg",e.getMessage());
        }
        return result;
    }

    @RequestMapping("/deleteButton")
    public Object deleteButton(String id){
        JSONObject result = new JSONObject();
        try{
            JSONObject json = JSON.parseObject(id);
            String results = HttpPOSTUtil.sendPost(Constants.deleteButtonUrl+"?access_token="+util.getToken(redisService),"");
            result.put("code", 200);
            result.put("data", JSON.parse(results));
        }catch (Exception e){
            e.printStackTrace();
            result.put("code",400);
            result.put("msg",e.getMessage());
        }
        return result;
    }

    //排序
    public String sort(String token, String timestamp, String nonce) {
        String[] strArray = {token, timestamp, nonce};
        Arrays.sort(strArray);
        StringBuilder sb = new StringBuilder();
        for (String str : strArray) {
            sb.append(str);
        }

        return sb.toString();
    }

    //签名加密
    public String sha1(String str) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-1");
            digest.update(str.getBytes());
            byte messageDigest[] = digest.digest();
            // Create Hex String
            StringBuffer hexString = new StringBuffer();
            // 字节数组转换为 十六进制 数
            for (int i = 0; i < messageDigest.length; i++) {
                String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexString.append(0);
                }
                hexString.append(shaHex);
            }
            return hexString.toString();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

}
